using System;
using System.Device.Location;
using System.Windows;
namespace Microsoft.Phone.Controls.Maps.Core
{
	public static class MercatorUtility
	{
		public const double MercatorLatitudeLimit = 85.051128;
		public const double EarthRadiusInMeters = 6378137.0;
		public const double EarthCircumferenceInMeters = 40075016.685578488;
		public static Point NormalizeLogicalPoint(Point logicalPoint, Point centerLogicalPoint)
		{
			if (logicalPoint.get_X() >= centerLogicalPoint.get_X() - 0.5 && logicalPoint.get_X() <= centerLogicalPoint.get_X() + 0.5)
			{
				return logicalPoint;
			}
			return new Point(logicalPoint.get_X() - Math.Floor(logicalPoint.get_X() - centerLogicalPoint.get_X() + 0.5), logicalPoint.get_Y());
		}
		public static GeoCoordinate NormalizeLocation(GeoCoordinate location)
		{
			GeoCoordinate geoCoordinate = new GeoCoordinate();
			geoCoordinate.set_Latitude(MercatorUtility.NormalizeLatitude(location.get_Latitude()));
			geoCoordinate.set_Longitude(MercatorUtility.NormalizeLongitude(location.get_Longitude()));
			return geoCoordinate;
		}
		public static double NormalizeLatitude(double latitude)
		{
			return Math.Min(Math.Max(latitude, -85.051128), 85.051128);
		}
		public static double NormalizeLongitude(double longitude)
		{
			if (longitude >= -180.0 && longitude <= 180.0)
			{
				return longitude;
			}
			return longitude - Math.Floor((longitude + 180.0) / 360.0) * 360.0;
		}
		public static Point LocationToLogicalPoint(GeoCoordinate location)
		{
			double num;
			if (location.get_Latitude() > 85.051128)
			{
				num = 0.0;
			}
			else
			{
				if (location.get_Latitude() < -85.051128)
				{
					num = 1.0;
				}
				else
				{
					double num2 = Math.Sin(location.get_Latitude() * 3.1415926535897931 / 180.0);
					num = 0.5 - Math.Log((1.0 + num2) / (1.0 - num2)) / 12.566370614359173;
				}
			}
			return new Point((location.get_Longitude() + 180.0) / 360.0, num);
		}
		public static GeoCoordinate LogicalPointToLocation(Point logicalPoint)
		{
			GeoCoordinate geoCoordinate = new GeoCoordinate();
			geoCoordinate.set_Latitude(90.0 - 360.0 * Math.Atan(Math.Exp((logicalPoint.get_Y() * 2.0 - 1.0) * 3.1415926535897931)) / 3.1415926535897931);
			geoCoordinate.set_Longitude(MercatorUtility.NormalizeLongitude(360.0 * logicalPoint.get_X() - 180.0));
			return geoCoordinate;
		}
		public static double ZoomToScale(Size logicalAreaSizeInScreenSpaceAtLevel1, double zoomLevel, GeoCoordinate location)
		{
			double num = 40075016.685578488 / (Math.Pow(2.0, zoomLevel - 1.0) * logicalAreaSizeInScreenSpaceAtLevel1.get_Width());
			return Math.Cos(MercatorUtility.DegreesToRadians(location.get_Latitude())) * num;
		}
		public static double ScaleToZoom(Size logicalAreaSizeInScreenSpaceAtLevel1, double scale, GeoCoordinate location)
		{
			double num = scale / Math.Cos(MercatorUtility.DegreesToRadians(location.get_Latitude()));
			return Math.Log(40075016.685578488 / (num * logicalAreaSizeInScreenSpaceAtLevel1.get_Width()), 2.0) + 1.0;
		}
		public static double DegreesToRadians(double deg)
		{
			return deg * 3.1415926535897931 / 180.0;
		}
	}
}
